# -*- coding: utf-8 -*-

"""
  @author: tangliqi
  @date: 2022/12/1 11:29
  @python version: 3.6 
  @contact me: 110
  ---------------------------------------
  @desc: python算法实现 => 可迭代对象、迭代器、生成器.py
"""

"""
# 容器：
python中一切皆对象，能够存储对象的集合，就称为容器；str/list/set/tuple等都是容器。

# 可迭代对象：
一个对象，实现了 __iter__ 方法，就是可迭代对象；__iter__ 方法需要返回一个迭代器。

# 迭代器：
一个对象同时实现了 __iter__ 和 __next__ 方法，那么它就是迭代器。

# for循环本质：
通过for循环对一个可迭代对象进行迭代时，for循环内部机制会自动通过调用iter()方法执行可迭代对象内部定义的__iter__()方法来获取一个迭代器，
然后一次又一次得迭代过程中通过调用next()方法执行迭代器内部定义的__next__()方法获取下一个元素，
当没有下一个元素时，for循环自动捕获并处理StopIteration异常。

# 生成器：
生成器是一种特殊的迭代器，生成器利用了惰性计算机制，不会一次性内存中加载所有数据，而是使用一个取一个。
因为只能用一个取一个，就导致获取长度等需要同时有多个元素的功能无法使用，所以根据场景考虑，是否使用生成器。
"""
from collections.abc import Iterator, Iterable, Generator


# ============== #
#   可迭代对象
# ============== #

# 实现了 __iter__ 方法，就是可迭代对象
class A:
    def __iter__(self):
        return self


def iterable():
    print(isinstance("123", Iterable))
    print(isinstance(123, Iterable))
    print(isinstance(tuple(), Iterable))
    print(isinstance(dict(), Iterable))
    print(isinstance(A, Iterable))  # False
    print(isinstance(A(), Iterable))  # True


# ============== #
#    迭代器
# ============== #
# 同时实现了 __iter__ 和 __next__ 方法，就是迭代器。
class B:
    def __iter__(self):
        return self

    def __next__(self):
        pass


def iterator():
    # 通过 iter() 方法将一个对象转换为迭代器
    a = list()
    a = iter(a)
    print(isinstance(a, Iterator))  # False
    print(isinstance(B(), Iterator))  # True
    print(isinstance(B, Iterator))  # False


# ============== #
#    生成器
# ============== #
def generator():
    for i in range(10):
        yield i


if __name__ == '__main__':
    # 可迭代对象
    iterable()

    # 迭代器
    iterator()

    # 生成器
    a = generator()
    print(isinstance(a, Generator))
